Skip to content

docs(specs): update auth-capture evm spec#2359

Draft
avidreder wants to merge 10 commits into
x402-foundation:mainfrom
avidreder:feat/update-auth-capture-spec
Draft

docs(specs): update auth-capture evm spec#2359
avidreder wants to merge 10 commits into
x402-foundation:mainfrom
avidreder:feat/update-auth-capture-spec

Conversation

@avidreder
Copy link
Copy Markdown
Contributor

@avidreder avidreder commented May 18, 2026

Description

Updates the auth-capture specs to make server-requested operations explicit:

  • Replace extra.autoCapture operation selection with payload.type for authorize, charge, capture, void, and refund.
  • Document the EVM mapping from each operation type to its AuthCaptureEscrow call.
  • Add compact per-operation payload field requirements, optional serverAuthorization, extra.serverAuthorizationRequired, smart contract operator guidance, and server self-facilitation guidance.

Tests

  • ReadLints diagnostics for touched markdown files: no linter errors.
  • Not run: full language test suites; docs/spec-only change.

Checklist

  • I have formatted and linted my code
  • All new and existing tests pass
  • My commits are signed (required for merge) -- you may need to rebase if you initially pushed unsigned commits
  • I added a changelog fragment for user-facing changes (docs-only changes can skip)

Document server-routed authCapture operations via payload type and remove autoCapture as the operation selector.

Co-authored-by: Cursor <[email protected]>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 18, 2026

@avidreder is attempting to deploy a commit to the Coinbase Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added the specs Spec changes or additions label May 18, 2026
avidreder and others added 2 commits May 18, 2026 16:08
Use authorize as the server operation discriminator while preserving authorization for token payload fields.

Co-authored-by: Cursor <[email protected]>
Add serverAuthorizationRequired to advertised authCapture requirements when facilitators require server identity proof.

Co-authored-by: Cursor <[email protected]>
@A1igator
Copy link
Copy Markdown
Contributor

A1igator commented May 18, 2026

@avidreder Not sure what the plan with this PR is since it's a draft but this is not the best design. Server interacting with the escrow should be coded in the captureAuthorizer smart contract itself and we already do so with our contracts.

You're adding a very specific style of captureAuthorizer (facilitator EOA) helpers, which a) as I mentioned before should be discouraged even if supported: #1425 (comment) and b) will be very confusing for anyone using the smart contract captureAuthorizer because the new functions added in the spec would be broken and c) Not really sure how this is supposed to work merchant developer experience wise. Would they change their endpoint and hit the facilitator directly? right now schemes are set and stay at each endpoint and clients hit them.

If there is any demand for this kind of structure anyways despite my objections above and how the same functionality can be done via captureAuthorizer smart contracts more trustlessly, I'd at least recommend an optional companion doc not in the main spec itself to not pollute it for smart contract captureAuthorizer use cases which is where we see most demand.

Would love to know @fabrice-cheng's thoughts as well.

avidreder and others added 6 commits May 20, 2026 08:41
Use charge for the single-shot authCapture operation instead of authorizeAndCapture.

Co-authored-by: Cursor <[email protected]>
Move the EVM-specific serverAuthorization wording into the EVM binding and keep the base authCapture spec network-neutral.

Co-authored-by: Cursor <[email protected]>
Document facilitator routing through captureAuthorizer contracts that expose the escrow operation interface.

Co-authored-by: Cursor <[email protected]>
State that captureAuthorizer is provided by the server in the generic authCapture spec.

Co-authored-by: Cursor <[email protected]>
Document gas and wallet safety expectations for facilitators calling smart contract operators.

Co-authored-by: Cursor <[email protected]>
Use auth-capture as the scheme name in the auth capture specs and examples.

Co-authored-by: Cursor <[email protected]>
@avidreder avidreder changed the title docs: update authCapture EVM spec docs: update auth-capture EVM spec May 20, 2026
@avidreder avidreder changed the title docs: update auth-capture EVM spec docs(specs): update auth-capture evm spec May 20, 2026
@phdargen phdargen self-assigned this May 21, 2026
@phdargen
Copy link
Copy Markdown
Collaborator

Thanks for the feedback @A1igator, sharing some context on design intent and addressing your concerns.

Background:

After authorize() or charge(), the authCapture lifecycle has operations (capture, void, refund) that are currently entirely out-of-band and not covered by the specs, x402 SDK or facilitator HTTP API. The question is how to bring these into the x402 protocol.

We generally target a gasless experience for both client and server for all operations and the point of the facilitator is to abstract away web3 complexities such that it becomes a choice: "Do I use an external facilitator for a simpler experience or do I self-facilitate and take on the web3 complexities like rpc config, wallet management and gas costs"?

We are not discouraging smart contract captureAuthorizer, this is a valid use case but we would like to offer a simple, in-protocol option for servers to call capture/void/refund via the facilitator.
batch-settlement already solves a structurally similar problem: the server asks the facilitator to execute onchain operations claim/settle/refund at some point after the client->server interaction. It does this via:

  • a ChannelManager that the server creates via scheme createChannelManager(facilitatorClient, network)
  • the channel manager calls facilitatorClient.settle() with different payload.type values ("claim", "settle", "refund")
  • the facilitator scheme dispatches on payload.type to different onchain functions
  • payloads include a signature from the server's receiverAuthorizer which are enforced onchain eliminating facilitator trust
  • no new HTTP endpoints, everything flows through the existing POST /settle surface

Following this pattern, the idea is:

  • a AuthCaptureManager via which the server calls the facilitator settle/ endpoint with payload types=capture/void/refund
  • in the simplest case captureAuthorizer=facilitator eoa
  • for a trustless setup, the spec would define an interface for captureAuthorizer contracts that verify EIP-712 signatures from a server-defined authorizer address mirroring batch-settlement's receiverAuthorizer. The facilitator relays server-signed payloads, and the contract enforces authorization onchain. We would appreciate your input on the ABI/typehash design given your experience developing operator contracts
  • ideally we would have a minimal reference contract for the sdk

This is not a blocker for #2308, which implements payload types charge/authorize, and can be a follow-up that implements payload types capture/void/refund as this should be purely additive. All we are asking for now is to redefine the payload shape from autoCapture=true/false to type=charge/authorize in anticipation of more types to be added later.

To your concerns:

  • a) operator contract validating EIP712 signatures as trustless option
  • b) settle with eg payload type=capture would branch on captureAuthorizer=facilitator eoa and captureAuthorizer=contract that implements the EIP712 interface or returns error_code
  • c) batch-settlement like devx, no additional endpoints

@A1igator
Copy link
Copy Markdown
Contributor

A1igator commented May 21, 2026

Thanks @phdargen for the explanation!

I need to digest this properly but one thing to note off the bat is that refund will need to accept multiple token collectors (as there's many scenarios like insurance pool or platform refund pool and more) and possibly different shapes of collector datas as well. Unsure how that would be usable by the server in this case without adding more fields? And if we are adding those fields back, should we add them back for charge and authorize too for consistency?

We could also default it to a very specific kind of token collector (like a server initiated refund or something) same way charge and authorize do, and leave the other options outside the main spec since they'd all need third parties with a custom captureAuthorizer contract anyways as far as I can tell.

Thanks again for the explanation and cooperation!

@A1igator
Copy link
Copy Markdown
Contributor

A1igator commented May 22, 2026

One more thing to clarify, "payloads include a signature from the server's receiverAuthorizer which are enforced onchain eliminating facilitator trust" would mean this direction is only defined for smart contract captureAuthorizer? Facilitator EOA case basically does not change and stays as is with no server connect functionality laid out in the spec?

I'm obviously happy with this as big trust minimization proponent. I can also provide a minimal reference contract that allows for server to do this no problem.

Edit: I also ask this because the simple facilitator EOA case would be pretty broken if all the functionality is allowed with this interface. Anyone would be able to call it and move escrow funds randomly causing chaos. serverAuthorization should be required for either case if both support this interface, but if following batch-settlement and to minimize trust, serverAuthorization should be checked by a smart contract.

Also just spitballing here, we could completely delete the facilitator EOA case because it causes these weird trust assumptions. I'm obviously biased but if the goal is trust minimization, simplifying things, and matching batch-settlement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

specs Spec changes or additions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants